home *** CD-ROM | disk | FTP | other *** search
- #include <string.h>
- #include <stdlib.h>
- #include "fstab.h"
- #include "../paths.h"
- #include "internal.h"
-
- FSTAB_HELP_FILE help_fstab ("fstab");
- static CONFIG_FILE f_fstab (ETC_FSTAB,help_fstab,CONFIGF_MANAGED);
-
- PRIVATE void FSTAB_ENTRY::init()
- {
- valid = 0;
- memset (&bool_opt,0,sizeof(bool_opt));
- msdos_opt.uid = msdos_opt.gid = msdos_opt.perm = MSDOS_OPT_UNUSE;
- nfs_opt.rsize = nfs_opt.wsize = NFS_OPT_UNUSE;
- nfs_opt.soft = nfs_opt.bg = 0;
- dumpfreq = fsckpriority = 1;
- }
-
- PUBLIC FSTAB_ENTRY::FSTAB_ENTRY()
- {
- init();
- }
-
- /*
- Analyse the option string xxx,yyy,zzz=val,...
- Some option are "known" by fsconf. Unknown one are left in
- an "option" string editable by the user. The known one have
- there own field in the FSTAB_ENTRY structure.
- */
- PUBLIC void FSTAB_ENTRY::parseopt(char *opts)
- {
- char other[200];
- other[0] = '\0';
- while (*opts != '\0'){
- char *debut = opts;
- char *equal = "";
- int seen_equal = 0;
- while (1){
- char *pt_carac = opts;
- char carac = *opts++;
- if (carac == '\0'){
- opts--;
- break;
- }else if (carac == ','){
- *pt_carac = '\0';
- break;
- }else if (carac == '='){
- equal = opts;
- *pt_carac = '\0';
- seen_equal = 1;
- }
- }
- if (strcmp(debut,"defaults")==0){
- // Do nothing here. The keyword defaults
- // is silently write back if no other option
- // is specified.
- }else if (strcmp(debut,"conv")==0){
- msdos_opt.conv.setfrom(equal);
- }else if (strcmp(debut,"uid")==0){
- msdos_opt.uid = atoi(equal);
- }else if (strcmp(debut,"gid")==0){
- msdos_opt.gid = atoi(equal);
- }else if (strcmp(debut,"perm")==0){
- msdos_opt.perm = atoi(equal);
- }else if (strcmp(debut,"noexec")==0){
- bool_opt.noexec = 1;
- }else if (strcmp(debut,"exec")==0){
- bool_opt.noexec = 0;
- }else if (strcmp(debut,"nosuid")==0){
- bool_opt.nosuid = 1;
- }else if (strcmp(debut,"suid")==0){
- bool_opt.nosuid = 0;
- }else if (strcmp(debut,"nodev")==0){
- bool_opt.nodev = 1;
- }else if (strcmp(debut,"dev")==0){
- bool_opt.nodev = 0;
- }else if (strcmp(debut,"user")==0){
- bool_opt.user = 1;
- bool_opt.nodev = 1;
- bool_opt.noexec = 1;
- bool_opt.nosuid = 1;
- }else if (strcmp(debut,"ro")==0){
- bool_opt.readonly = 1;
- }else if (strcmp(debut,"rw")==0){
- bool_opt.readonly = 0;
- }else if (strcmp(debut,"noauto")==0){
- bool_opt.noauto = 1;
- }else if (strcmp(debut,"soft")==0){
- nfs_opt.soft = 1;
- }else if (strcmp(debut,"bg")==0){
- nfs_opt.bg = 1;
- }else if (strcmp(debut,"rsize")==0){
- nfs_opt.rsize = atoi(equal);
- }else if (strcmp(debut,"wsize")==0){
- nfs_opt.wsize = atoi(equal);
- }else if (strcmp(debut,"addr")!=0){
- // This is the other option still unknown by linuxconf
- // note that the simili addr option used by NFS in /etc/mtab
- // is ignored.
- if (other[0] != '\0') strcat (other,",");
- strcat (other,debut);
- if (seen_equal){
- strcat (other,"=");
- strcat (other,equal);
- }
- }
- }
- options.setfrom (other);
- }
- /*
- Build an FSTAB_ENTRY from a line of the /etc/fstab file
- */
- PUBLIC FSTAB_ENTRY::FSTAB_ENTRY (const char *line)
- {
- init();
- line = str_skip (line);
- if (*line != '\0'){
- if (*line == '#'){
- comment.setfrom(line);
- }else{
- char buf[1000];
- strcpy (buf,line);
- char *pt1 = strtok (buf," \t");
- char *pt2 = strtok (NULL," \t");
- char *pt3 = strtok (NULL," \t");
- char *pt4 = strtok (NULL," \t");
- char *pt5 = strtok (NULL," \t");
- char *pt6 = strtok (NULL," \t");
- if (pt4 != NULL){
- source.setfrom(pt1);
- mpoint.setfrom(pt2);
- type.setfrom (pt3);
- parseopt (pt4);
- if (pt5 != NULL) dumpfreq = atoi(pt5);
- if (pt6 != NULL) fsckpriority = atoi(pt6);
- valid = 1;
- }else{
- comment.setfrom(str_skip(line));
- }
- }
- }
- }
- static void opt_put_if (
- char *out,
- char bool_opt,
- const char *name,
- int &was_written)
- {
- if (bool_opt){
- if (was_written) strcat (out,",");
- was_written = 1;
- strcat (out,name);
- }
- }
- static void opt_put_if (
- char *out,
- char bool_opt,
- const char *noname,
- const char *name,
- int &was_written)
- {
- if (was_written) strcat (out,",");
- was_written = 1;
- strcat (out,bool_opt ? noname : name);
- }
- static void opt_put_if (
- char *out,
- int value,
- const char *name,
- int &was_written)
- {
- if (value != MSDOS_OPT_UNUSE){
- if (was_written) strcat (out,",");
- was_written = 1;
- char buf[100];
- sprintf (buf,"%s=%d",name,value);
- strcat (out,buf);
- }
- }
- static void opt_put_if (
- char *out,
- const char *value,
- const char *name,
- int &was_written)
- {
- if (value[0] != '\0'){
- if (was_written) strcat (out,",");
- was_written = 1;
- char buf[100];
- sprintf (buf,"%s=%s",name,value);
- strcat (out,buf);
- }
- }
-
- /*
- Format all the mount option in a string suitable for the mount command
- if tosave != 0, it also adds the options only meaningful in /etc/fstab
- (user,noauto,...)
- */
- PUBLIC void FSTAB_ENTRY::format_opt(int tosave, char *str) const
- {
- int one = 0;
- str[0] = '\0';
- if (tosave) opt_put_if (str,bool_opt.user,"user",one);
- opt_put_if (str,bool_opt.noexec,"noexec","exec",one);
- opt_put_if (str,bool_opt.nodev,"nodev","dev",one);
- opt_put_if (str,bool_opt.nosuid,"nosuid","suid",one);
- opt_put_if (str,bool_opt.readonly,"ro","rw",one);
- if (tosave) opt_put_if (str,bool_opt.noauto,"noauto",one);
- opt_put_if (str,msdos_opt.conv.get(),"conv",one);
- opt_put_if (str,msdos_opt.uid,"uid",one);
- opt_put_if (str,msdos_opt.gid,"gid",one);
- opt_put_if (str,msdos_opt.perm,"perm",one);
- opt_put_if (str,nfs_opt.bg,"bg",one);
- opt_put_if (str,nfs_opt.soft,"soft",one);
- opt_put_if (str,nfs_opt.rsize,"rsize",one);
- opt_put_if (str,nfs_opt.wsize,"wsize",one);
- if (!options.is_empty()){
- if (one) strcat (str,",");
- strcat (str,options.get());
- }else if (!one){
- if (tosave) strcpy (str,"defaults");
- }
- }
-
- /*
- Write an entry into /etc/fstab
- */
- PUBLIC void FSTAB_ENTRY::print (FILE *fout) const
- {
- if (valid){
- fprintf (fout,"%s\t%s\t%s\t",source.get(),mpoint.get()
- ,type.get());
- char str[200];
- format_opt (1,str);
- fprintf (fout," %s %d %d",str,dumpfreq,fsckpriority);
- }else{
- fputs (comment.get(),fout);
- }
- fputc ('\n',fout);
- }
-
- /*
- Return != 0 if this entry is ok (not a comment).
- */
- PUBLIC int FSTAB_ENTRY::is_valid() const
- {
- return valid;
- }
-
-
- /*
- Tell if this mount should be done at boot time.
- */
- PUBLIC int FSTAB_ENTRY::is_auto()
- {
- return !bool_opt.noauto;
- }
-
- /*
- Return != 0 if the entry describe a mount of a remote volume
- either with NFS or SMBFS.
- */
- PUBLIC int FSTAB_ENTRY::is_remote() const
- {
- return type.cmp("nfs")==0 || type.cmp("smbfs")==0;
- }
- /*
- Return != 0 if the entry describe a swap file or partition.
- */
- PUBLIC int FSTAB_ENTRY::is_swap() const
- {
- return type.cmp("swap")==0;
- }
- /*
- Return the file system type ID
- */
- PUBLIC FSTAB_ENTRY_TYPE FSTAB_ENTRY::gettype() const
- {
- FSTAB_ENTRY_TYPE ret = FSTAB_ENTRY_LOCAL;
- if (is_swap()){
- ret = FSTAB_ENTRY_SWAP;
- }else if (type.cmp("nfs")==0){
- ret = FSTAB_ENTRY_NFS;
- }else if (type.cmp("smbfs")==0){
- ret = FSTAB_ENTRY_SAMBA;
- }else if (type.cmp("proc")==0){
- ret = FSTAB_ENTRY_PROC;
- }
- return ret;
- }
- /*
- Return the file systeme type (ascii).
- */
- PUBLIC const char *FSTAB_ENTRY::getfs() const
- {
- return type.get();
- }
-
- /*
- Return the source of the mount (either the device or the remote volume)
- */
- PUBLIC const char *FSTAB_ENTRY::getsource() const
- {
- return source.get();
- }
-
- /*
- Record a new device / remote volume for a FSTAB_ENTRY
- */
- PUBLIC void FSTAB_ENTRY::setsource(const char *path)
- {
- source.setfrom (path);
- setmodified();
- }
- /*
- Return the mount point
- */
- PUBLIC const char *FSTAB_ENTRY::getmpoint() const
- {
- return mpoint.get();
- }
-
- /*
- Return the comment of the entry
- */
- PUBLIC const char *FSTAB_ENTRY::getcomment()
- {
- return comment.get();
- }
-
-
- PUBLIC FSTAB::FSTAB ()
- {
- FILE *fin = f_fstab.fopen("r");
- if (fin != NULL){
- char buf[1000];
- while (fgets_cont(buf,sizeof(buf)-1,fin) != -1){
- add (new FSTAB_ENTRY(buf));
- }
- fclose (fin);
- }
- rstmodified();
- }
- /*
- Return one entry of the fstab file.
- Returne NULL if the entry is out of range.
- */
- PUBLIC FSTAB_ENTRY *FSTAB_GEN::getitem(int no)
- {
- return (FSTAB_ENTRY*)ARRAY::getitem(no);
- }
-
- /*
- Write a /etc/fstab file
- Return -1 if any error.
- */
- PUBLIC int FSTAB::write ()
- {
- int ret = -1;
- FILE *fout = f_fstab.fopen ("w");
- if (fout != NULL){
- ret = 0;
- for (int i=0; i<nb; i++) getitem(i)->print (fout);
- fclose (fout);
- }
- return ret;
- }
-
- #ifdef TEST
-
- int main (int argc, char *argv[])
- {
- FSTAB fs;
- fs.write();
- return 0;
- }
-
- #endif
-
-